package 结构性模式

import java.lang.Exception
import java.lang.RuntimeException
import java.util.concurrent.Callable

/**
 * 将一个类的接口转换成客户希望的另外一个接口
 * 使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
 */
class Task(private val num: Long) : Callable<Long> {
    override fun call(): Long {
        var result = 0L
        for (n in 1 until num) {
            result += n
        }
        println("Result: $result")
        return result
    }

}


/**
 * Adapter
 * 实现目标接口，这里是Runnable；
 * 内部持有一个待转换接口的引用，这里是通过字段持有Callable接口；
 * 在目标接口的实现方法内部，调用待转换接口的方法。
 */

class RunnableAdapter(private val callable: Callable<*>) : Runnable {
    override fun run() {
        try {
            callable.call()
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
    }

}


fun main2() {
    val callable = Task(1234L)
    Thread(RunnableAdapter(callable)).start()
}

// 目标接口
interface MediaPlayer {
    fun play(filename: String)
}

// 被适配者（旧的英文播放器）
class EnglishMediaPlayer {
    fun playEnglish(filename: String) {
        println("Playing English music: $filename")
    }
}

// 适配器（将英文播放器适配成中文播放器）
class ChineseMediaPlayerAdapter(private val englishPlayer: EnglishMediaPlayer) : MediaPlayer {
    override fun play(filename: String) {
        // 这儿可以是预处理...
        // 使用适配器调用旧的英文播放器的方法
        englishPlayer.playEnglish(filename)
    }
}

// 客户端代码
fun main() {
    // 创建英文播放器对象
    val englishPlayer = EnglishMediaPlayer()

    // 创建中文播放器适配器对象
    val adapter = ChineseMediaPlayerAdapter(englishPlayer)

    // 使用中文播放器播放音乐
    adapter.play("中国之声.mp3")
}